//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.activiti.editor.language.json.converter;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.bpmn.model.*;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

public class SequenceFlowJsonConverter extends BaseBpmnJsonConverter {


    public SequenceFlowJsonConverter() {
    }

    public static void fillTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap, Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        fillJsonTypes(convertersToBpmnMap);
        fillBpmnTypes(convertersToJsonMap);
    }

    public static void fillJsonTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap) {
        convertersToBpmnMap.put("SequenceFlow", SequenceFlowJsonConverter.class);
    }

    public static void fillBpmnTypes(Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {
        convertersToJsonMap.put(SequenceFlow.class, SequenceFlowJsonConverter.class);
    }

    protected String getStencilId(BaseElement baseElement) {
        return "SequenceFlow";
    }

    public void convertToJson(BaseElement baseElement, ActivityProcessor processor, BpmnModel model, FlowElementsContainer container, ArrayNode shapesArrayNode, double subProcessX, double subProcessY) {
        SequenceFlow sequenceFlow = (SequenceFlow)baseElement;
        ObjectNode flowNode = BpmnJsonConverterUtil.createChildShape(sequenceFlow.getId(), "SequenceFlow", 172.0D, 212.0D, 128.0D, 212.0D);
        ArrayNode dockersArrayNode = this.objectMapper.createArrayNode();
        ObjectNode dockNode = this.objectMapper.createObjectNode();
        dockNode.put("x", model.getGraphicInfo(sequenceFlow.getSourceRef()).getWidth() / 2.0D);
        dockNode.put("y", model.getGraphicInfo(sequenceFlow.getSourceRef()).getHeight() / 2.0D);
        dockersArrayNode.add(dockNode);
        if (model.getFlowLocationGraphicInfo(sequenceFlow.getId()).size() > 2) {
            for(int i = 1; i < model.getFlowLocationGraphicInfo(sequenceFlow.getId()).size() - 1; ++i) {
                GraphicInfo graphicInfo = (GraphicInfo)model.getFlowLocationGraphicInfo(sequenceFlow.getId()).get(i);
                dockNode = this.objectMapper.createObjectNode();
                dockNode.put("x", graphicInfo.getX());
                dockNode.put("y", graphicInfo.getY());
                dockersArrayNode.add(dockNode);
            }
        }

        dockNode = this.objectMapper.createObjectNode();
        dockNode.put("x", model.getGraphicInfo(sequenceFlow.getTargetRef()).getWidth() / 2.0D);
        dockNode.put("y", model.getGraphicInfo(sequenceFlow.getTargetRef()).getHeight() / 2.0D);
        dockersArrayNode.add(dockNode);
        flowNode.put("dockers", dockersArrayNode);
        ArrayNode outgoingArrayNode = this.objectMapper.createArrayNode();
        outgoingArrayNode.add(BpmnJsonConverterUtil.createResourceNode(sequenceFlow.getTargetRef()));
        flowNode.put("outgoing", outgoingArrayNode);
        flowNode.put("target", BpmnJsonConverterUtil.createResourceNode(sequenceFlow.getTargetRef()));
        ObjectNode propertiesNode = this.objectMapper.createObjectNode();
        propertiesNode.put("overrideid", sequenceFlow.getId());
        if (StringUtils.isNotEmpty(sequenceFlow.getName())) {
            propertiesNode.put("name", sequenceFlow.getName());
        }

        if (StringUtils.isNotEmpty(sequenceFlow.getDocumentation())) {
            propertiesNode.put("documentation", sequenceFlow.getDocumentation());
        }

        if (StringUtils.isNotEmpty(sequenceFlow.getConditionExpression())) {
            propertiesNode.put("conditionsequenceflow", sequenceFlow.getConditionExpression());
        }

        if (StringUtils.isNotEmpty(sequenceFlow.getSourceRef())) {
            FlowElement sourceFlowElement = container.getFlowElement(sequenceFlow.getSourceRef());
            if (sourceFlowElement != null) {
                String defaultFlowId = null;
                if (sourceFlowElement instanceof ExclusiveGateway) {
                    ExclusiveGateway parentExclusiveGateway = (ExclusiveGateway)sourceFlowElement;
                    defaultFlowId = parentExclusiveGateway.getDefaultFlow();
                } else if (sourceFlowElement instanceof Activity) {
                    Activity parentActivity = (Activity)sourceFlowElement;
                    defaultFlowId = parentActivity.getDefaultFlow();
                }

                if (defaultFlowId != null && defaultFlowId.equals(sequenceFlow.getId())) {
                    propertiesNode.put("defaultflow", true);
                }
            }
        }

        if (sequenceFlow.getExecutionListeners().size() > 0) {
            BpmnJsonConverterUtil.convertListenersToJson(sequenceFlow.getExecutionListeners(), true, propertiesNode);
        }

        flowNode.put("properties", propertiesNode);
        shapesArrayNode.add(flowNode);
    }

    protected void convertElementToJson(ObjectNode propertiesNode, BaseElement baseElement) {



    }

    protected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode, Map<String, JsonNode> shapeMap) {
        SequenceFlow flow = new SequenceFlow();
        String sourceRef = BpmnJsonConverterUtil.lookForSourceRef(elementNode.get("resourceId").asText(), modelNode.get("childShapes"));
        JsonNode conditionNode;
        if (sourceRef != null) {
            flow.setSourceRef(sourceRef);
            conditionNode = elementNode.get("target");
            if (conditionNode != null && !conditionNode.isNull()) {
                String targetId = conditionNode.get("resourceId").asText();
                if (shapeMap.get(targetId) != null) {
                    flow.setTargetRef(BpmnJsonConverterUtil.getElementId((JsonNode)shapeMap.get(targetId)));
                }
            }
        }

        //如果id为空则设置一个ID
//        String overrideid = getPropertyValueAsString("overrideid", elementNode);
//        if (StringUtils.isBlank(overrideid)){
//            if (elementNode.get("properties") != null) {
//                JsonNode propertiesNode = (ObjectNode)elementNode.get("properties");
//                ((ObjectNode) propertiesNode).put("overrideid","lxy_"+IdGen.uuid());
//            }
//        }

        //保存国际化
//        ActMessage actMessage = new ActMessage();
//        actMessage.setActId(getPropertyValueAsString("overrideid", elementNode));
//        actMessage.setEnUs(getPropertyValueAsString("enusname", elementNode));
//        actMessage.setZhTw(getPropertyValueAsString("zhtwname", elementNode));
//        actMessage.setJaJp(getPropertyValueAsString("jajpname", elementNode));
//        actMessage.setProcDefId(getPropertyValueAsString("process_id", modelNode));
//        actMessageService.save(actMessage);


        conditionNode = this.getProperty("conditionsequenceflow", elementNode);
        if (conditionNode != null) {
            if (conditionNode.isTextual() && !conditionNode.isNull()) {
                flow.setConditionExpression(conditionNode.asText());
            } else if (conditionNode.get("expression") != null) {
                JsonNode expressionNode = conditionNode.get("expression");
                if (expressionNode.get("type") != null) {
                    String expressionType = expressionNode.get("type").asText();
                    if ("variables".equalsIgnoreCase(expressionType) && expressionNode.get("fieldType") != null) {
                        String fieldType = expressionNode.get("fieldType").asText();
                        if ("field".equalsIgnoreCase(fieldType)) {
                            this.setFieldConditionExpression(flow, expressionNode);
                        } else if ("outcome".equalsIgnoreCase(fieldType)) {
                            this.setOutcomeConditionExpression(flow, expressionNode);
                        }
                    } else if (expressionNode.get("staticValue") != null && !expressionNode.get("staticValue").isNull()) {
                        flow.setConditionExpression(expressionNode.get("staticValue").asText());
                    }
                }
            }
        }

        return flow;
    }

    protected void setFieldConditionExpression(SequenceFlow flow, JsonNode expressionNode) {
        String fieldId = null;
        if (expressionNode.get("fieldId") != null && !expressionNode.get("fieldId").isNull()) {
            fieldId = expressionNode.get("fieldId").asText();
        }

        String operator = null;
        if (expressionNode.get("operator") != null && !expressionNode.get("operator").isNull()) {
            operator = expressionNode.get("operator").asText();
        }

        String value = null;
        if (expressionNode.get("value") != null && !expressionNode.get("value").isNull()) {
            value = expressionNode.get("value").asText();
        }

        if (fieldId != null && operator != null && value != null) {
            flow.setConditionExpression("${" + fieldId + " " + operator + " " + value + "}");
            this.addExtensionElement("conditionFieldId", fieldId, flow);
            this.addExtensionElement("conditionOperator", operator, flow);
            this.addExtensionElement("conditionValue", value, flow);
        }

    }

    protected void setOutcomeConditionExpression(SequenceFlow flow, JsonNode expressionNode) {
        Long formId = null;
        if (expressionNode.get("outcomeFormId") != null && !expressionNode.get("outcomeFormId").isNull()) {
            formId = expressionNode.get("outcomeFormId").asLong();
        }

        String operator = null;
        if (expressionNode.get("operator") != null && !expressionNode.get("operator").isNull()) {
            operator = expressionNode.get("operator").asText();
        }

        String outcomeName = null;
        if (expressionNode.get("outcomeName") != null && !expressionNode.get("outcomeName").isNull()) {
            outcomeName = expressionNode.get("outcomeName").asText();
        }

        if (formId != null && operator != null && outcomeName != null) {
            flow.setConditionExpression("${form" + formId + "outcome " + operator + " " + outcomeName + "}");
            this.addExtensionElement("conditionFormId", String.valueOf(formId), flow);
            this.addExtensionElement("conditionOperator", operator, flow);
            this.addExtensionElement("conditionOutcomeName", outcomeName, flow);
        }

    }

    protected void addExtensionElement(String name, String value, SequenceFlow flow) {
        ExtensionElement extensionElement = new ExtensionElement();
        extensionElement.setNamespace("http://activiti.com/modeler");
        extensionElement.setNamespacePrefix("modeler");
        extensionElement.setName(name);
        extensionElement.setElementText(value);
        flow.addExtensionElement(extensionElement);
    }
}
